package org.finesys.system.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.servlet.http.HttpServletResponse;

import org.finesys.common.core.module.R;
import org.finesys.common.file.client.FileTemplate;
import org.finesys.common.file.properties.FileProperties;
import org.finesys.common.mp.core.service.impl.BaseServiceImpl;
import org.finesys.system.api.entity.SysFile;
import org.finesys.system.mapper.SysFileMapper;
import org.finesys.system.service.SysFileService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.util.IOUtils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Service
@AllArgsConstructor
@Slf4j
public class SysFileServiceImpl extends BaseServiceImpl<SysFileMapper, SysFile> implements SysFileService {

    private final FileTemplate fileTemplate;
    private final FileProperties fileProperties;

    @Override
    @SneakyThrows
    public R<?> uploadFile(MultipartFile file) {
        String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());
        Map<String, String> resultMap = new HashMap<>(3);
        resultMap.put("bucketName", fileProperties.getBucketName());
        resultMap.put("fileName", fileName);
        resultMap.put("url", String.format("/admin/file/%s/%s", fileProperties.getBucketName(), fileName));
        try {
            fileTemplate.putObject(fileProperties.getBucketName(), fileName, file.getInputStream(), file.getContentType());
            // 文件管理数据记录,收集管理追踪文件
            fileLog(file, fileName);
        } catch (IOException e) {
            log.error("上传失败", e);
            return R.failed(e.getLocalizedMessage());
        }
        return R.success(resultMap);
    }

    @Override
    public void getFile(String bucket, String fileName, HttpServletResponse response) {
        try (S3Object s3Object = fileTemplate.getObject(bucket, fileName)) {
            response.setContentType("application/octet-stream;charset=UTF-8");
            IOUtils.copy(s3Object.getObjectContent(), response.getOutputStream());
        } catch (Exception e) {
            log.error("文件读取异常: {}", e.getLocalizedMessage());
        }
    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteFile(Long id) {
        SysFile file = this.getById(id);
        if (Objects.isNull(file)) {
            return Boolean.FALSE;
        }
        fileTemplate.removeObject(fileProperties.getBucketName(), file.getFileName());
        return this.removeById(id);
    }


    private void fileLog(MultipartFile file, String fileName) {
        SysFile sysFile = new SysFile();
        sysFile.setFileName(fileName);
        sysFile.setFileSize(file.getSize());
        sysFile.setType(FileUtil.extName(file.getOriginalFilename()));
        sysFile.setOriginal(file.getOriginalFilename());
        sysFile.setBucketName(fileProperties.getBucketName());
        this.save(sysFile);
    }
}
